package com.milling.quartz.service;

import com.milling.business.BusinessConstants;
import com.milling.business.GlobalVariable;
import com.milling.business.domain.WmsCellInfo;
import com.milling.business.domain.WmsTaskInfo;
import com.milling.business.mapper.WmsCellInfoMapper;
import com.milling.business.mapper.WmsNeedleCacheMapper;
import com.milling.business.service.*;
import com.milling.common.core.redis.RedisCache;
import com.milling.common.utils.SocketUtils;
import com.milling.common.utils.modbus.ModbusMasterPoolFactory;
import com.milling.common.utils.modbus.ModbusServiceFactory;
import com.milling.common.utils.modbus.ModbusTcpService;
import com.milling.common.utils.modbus.ModbusTcpServiceImpl;
import com.milling.common.utils.scanner.SocketListener;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import org.apache.commons.pool2.ObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.Socket;
import java.util.List;

//XXXXXXXXX
@Configuration
@ConditionalOnProperty(
        name = "mac.type",
        havingValue = "1",
        matchIfMissing = false // 当配置缺失时不加载
)
@Component
public class ScheduledTasks {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);

    // 从参数中读取IP、端口、slaveId和连接池大小
    @Value("${modbus.tcp.host:192.168.237.88}") // 默认值防止未配置
    private String host;

    @Value("${modbus.tcp.port:502}")
    private int port;

    @Value("${modbus.tcp.poolSize:5}")
    private int poolSize;

    @Value("${modbus.tcp.slaveId:1}")
    private int slaveId;

    @Value("${storage.ip}")
    private String storageIp;

    @Value("${storage.port}")
    private int storagePort;

//    @Autowired
//    private ModbusUtil modbusUtil;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IWmsCellInfoService wmsCellInfoService;

    @Autowired
    private IWmsTaskInfoService wmsTaskInfoService;

    @Autowired
    private WmsNeedleCacheMapper wmsNeedleCacheMapper;

    @Autowired
    private WmsCellInfoMapper wmsCellInfoMapper;

    // 获取Modbus服务实例
    private ModbusTcpService modbusTcpService;

    @PostConstruct
    public void init() {
        // 初始化 Modbus 服务
        modbusTcpService = ModbusServiceFactory.getModbusService(host, port, poolSize);
        logger.info("ScheduledTasks Modbus服务初始化完成 - {}:{}", host, port);

        // 初始化扫码器连接
//        initConnection();
    }

    // 每500毫秒执行一次
    @Scheduled(fixedRate = 500)
    public void executeTask() {
        // 这里添加你的业务逻辑
//        logger.info("定时任务执行，间隔0.5秒");

        // 创建连接池
//        ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//        ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);

        try {
//            int registerAddress = 550;
            int startAddress = 549;
            int numberOfRegisters = 25;

            // 示例：读取单个保持寄存器
            short[] numbers = new short[numberOfRegisters];
            // 示例：读取多个保持寄存器
            short[] values = modbusTcpService.readHoldingRegisters(slaveId, startAddress, numberOfRegisters);
            for (int i = 0; i < values.length; i++) {
                if (values[i] == 1) {//需要复位
                    onRegisterChange(startAddress + i);
                }
            }
        } catch (ModbusTransportException e) {
            e.printStackTrace();
        } catch (Exception e) {
            logger.error("读取寄存器地址  失败");
            e.printStackTrace();
//        } finally {
//            // 关闭连接池
//            modbusMasterPool.close();
        }
    }

    public void onRegisterChange(int registerAddress) {
//        log.info("Register {} changed from {} to {}", registerAddress, oldValue, newValue);
//        logger.info("寄存器 {} 为 1", registerAddress);
        // 创建连接池
//        ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
        try {
            // 创建ModbusService实例
//            ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);
            switch (registerAddress) {
                case 550:
                    try {
                        //扫码，在配针机代码左处理
                        Thread.sleep(50);
                        SocketUtils socketUtils = new SocketUtils(storageIp, storagePort);
                        socketUtils.sendMessage("start");
                        socketUtils.disconnect();
                        socketUtils.destroy();
//                        Thread.sleep(50);
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.error("SocketUtils sendMessage Fail");
                        modbusTcpService.writeHoldingRegister(slaveId, 550, 100);
                    }
                    break;
                case 551:
                    handleRegisterChange(modbusTcpService, registerAddress, "已将针盒送至配针机(后库直通)");
                    //修改 下料的缓存库位置 和 配针缓存区位置
                    break;
                case 552:
                    handleRegisterChange(modbusTcpService, registerAddress, "已将针盒送至配针机");
                    //修改 下料的缓存库位置 和 配针缓存区位置
                    break;
                case 557:
                    handleRegisterChange(modbusTcpService, registerAddress, "已将入料针盒放入");
                    //后库入库，依据扫码结果处理
                    wmsTaskInfoService.process557();
//                    completeReturnTask();
                    break;
                case 554:
                    handleRegisterChange(modbusTcpService, registerAddress, "已将回流针盒放入");
                    wmsTaskInfoService.process554();
//                    completeTask("557", "556", "");
                    break;
                case 560:
                    handleRegisterChange(modbusTcpService, registerAddress, "缓存立库已出料完成");

                    WmsCellInfo wmsCellInfoQuery = new WmsCellInfo();
                    wmsCellInfoQuery.setCellStatus(BusinessConstants.CELL_STATUS_4);
                    List<WmsCellInfo> list2 = wmsCellInfoService.selectWmsCellInfoList(wmsCellInfoQuery);
                    for (int i = 0; i < list2.size(); i++) {
                        wmsCellInfoQuery = list2.get(i);
                        wmsCellInfoQuery.setCellStatus(BusinessConstants.CELL_STATUS_1);
                        wmsCellInfoMapper.updateWmsCellInfo(wmsCellInfoQuery);
                    }

                    //此处加入补料条件更安全完善
//                    wmsTaskInfoService.feedingMixV();
//                    completeTask("560", "559", "510");
                    break;
                case 570:
/*
                    int configTrayCompleteFlag = modbusTcpService.readHoldingRegister(slaveId, 512);
                    if(configTrayCompleteFlag == 1) {
                        if (GlobalVariable.CONFIG_TRAY == 0 || GlobalVariable.CONFIG_TRAY == 1) {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                            GlobalVariable.CONFIG_TRAY = 2;
                        }
                        //混合处理，清0 START
                        modbusTcpService.writeHoldingRegister(slaveId, 512, 0);//切换配针托盘
                        //混合处理，清0 END

                        handleRegisterChange(modbusTcpService, registerAddress, "左补料到达入料口");
                    }
*/
                    break;
                case 571:
/*
                    int configTrayCompleteFlag2 = modbusTcpService.readHoldingRegister(slaveId, 512);
                    if(configTrayCompleteFlag2 == 1) {
                        if (GlobalVariable.CONFIG_TRAY == 0 || GlobalVariable.CONFIG_TRAY == 2) {
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                            GlobalVariable.CONFIG_TRAY = 1;
                        }
                        handleRegisterChange(modbusTcpService, registerAddress, "右补料到达入料口");
                    }
*/
                    break;
                case 572:
                    handleRegisterChange(modbusTcpService, registerAddress, "整个托盘配针完成");
                    break;
                default:
//                    logger.info("Register address " + registerAddress + " is out of range");
                    break;
            }
        } catch (ModbusTransportException e) {
            e.printStackTrace();
            logger.error("写入寄存器地址 "+registerAddress+" 失败");
//            throw new RuntimeException(e);
//        } finally {
//            modbusMasterPool.close();
        }
    }

    /**
     * 处理寄存器变化逻辑
     *
     * @param modbusTcpService Modbus TCP 服务
     * @param registerAddress  寄存器地址
     * @param description     寄存器描述
     * @throws ModbusTransportException Modbus通信异常
     */
    private void handleRegisterChange(ModbusTcpService modbusTcpService, int registerAddress, String description)
            throws ModbusTransportException {
        modbusTcpService.writeHoldingRegister(slaveId, registerAddress, 0);
        logger.info("Handled register address {}: {}", registerAddress, description);
    }

    private void completeReturnTask() {

    }

}
